package easier.app.x.result.location;

import android.Manifest.permission;
import android.app.Activity;
import android.content.Context;
import androidx.activity.result.ActivityResult;
import androidx.activity.result.ActivityResultCallback;
import androidx.annotation.IntDef;
import androidx.fragment.app.FragmentManager;
import easier.app.x.CommonCode;
import easier.app.x.result.Permission;
import easier.app.x.result.starter.StartForResult;
import easier.app.x.starter.IntentBuilder;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.util.Map;

/**
 * 该类用于简化处理定位相关流程,按照申请权限->打开定位服务的基础流程处理
 * {@link #processRequestForPermission(Runnable, Runnable)},弹出定位权限申请系统弹窗之前先解释下为什么需要位置信息
 * {@link #processShouldShowRequestPermissionRationale(Runnable, Runnable)},已经拒绝位置信息权限,解释下为什么需要,然后引导到app详情界面,权限处理
 * {@link #processLocationServiceSetting(Runnable, Runnable)},没有打开定位服务,解释需要打开定位服务的原因,引导到系统设置打开定位服务
 */
public class LocationPermissionServiceFunction {

    /**
     * 用于{@link #notifyFailedResult(int)},通知结果
     * 没有打开定位服务的结果
     */
    public static final int LOCATION_SERVICE_SETTING_CLOSE = 1;
    /**
     * 用于{@link #notifyFailedResult(int)},通知结果
     * 权限申请通过的结果,没有打开定位服务
     */
    public static final int LOCATION_PERMISSION_DENY = 2;
    /**
     * 用于{@link #notifyFailedResult(int)},通知结果
     * 权限申请通过,定位服务通过
     */
    public static final int LOCATION_FUNCTION_FINE = 3;

    @IntDef( {LOCATION_SERVICE_SETTING_CLOSE, LOCATION_PERMISSION_DENY, LOCATION_FUNCTION_FINE} )
    @Retention( RetentionPolicy.SOURCE )
    public @interface LocationResult {

    }

    protected Context mContext;

    /**
     * @param context 必须为activity的context
     */
    public LocationPermissionServiceFunction( Context context ) {

        mContext = context;
    }

    /**
     * 快速处理位置信息,定位服务,并有解释
     *
     * @param manager       权限处理
     * @param hasPermission 全部通过之后的处理流程
     */
    public void quickProcessLocationPermissionService( FragmentManager manager, Runnable hasPermission ) {

        Context context = mContext;
        boolean checkFine = Permission.check( context, permission.ACCESS_FINE_LOCATION );
        boolean checkCoarse = Permission.check( context, permission.ACCESS_COARSE_LOCATION );

        /*检查位置服务权限*/
        if ( checkFine || checkCoarse ) {
            /*有位置权限*/
            if ( CommonCode.couldLocation( context ) ) {
                /*有位置权限，有位置服务*/
                notifyFailedResult( LOCATION_FUNCTION_FINE );
                if ( hasPermission != null ) {
                    hasPermission.run();
                }
            } else {
                /*有位置权限，没有位置服务，弹出解释位置服务窗口，手机设置里打开*/
                processLocationServiceSetting( new Runnable() {
                    @Override
                    public void run() {
                        /*有位置权限，没有位置服务，弹出解释位置服务窗口，手机设置里打开，去设置界面*/
                        StartForResult.registerForActivityResult( manager, IntentBuilder.settingIntent(),
                            new ActivityResultCallback< ActivityResult >() {
                                @Override
                                public void onActivityResult( ActivityResult result ) {

                                    if ( CommonCode.couldLocation( context ) ) {
                                        /*有位置权限，没有位置服务，弹出解释位置服务窗口，手机设置里打开，去设置界面，打开了定位服务*/
                                        notifyFailedResult( LOCATION_FUNCTION_FINE );
                                        if ( hasPermission != null ) {
                                            hasPermission.run();
                                        }
                                    } else {
                                        /*有位置权限，没有位置服务，弹出解释位置服务窗口，手机设置里打开，去设置界面，没有打开定位服务*/
                                        notifyFailedResult( LOCATION_SERVICE_SETTING_CLOSE );
                                    }
                                }
                            } );
                    }
                }, new Runnable() {
                    @Override
                    public void run() {
                        /*有位置权限，没有位置服务，弹出解释位置服务窗口，手机设置里打开，不去设置界面*/
                        notifyFailedResult( LOCATION_SERVICE_SETTING_CLOSE );
                    }
                } );
            }
        } else {
            /*没有定位权限*/
            boolean checkShouldShowFine = Permission.shouldShowRequestPermissionRationale( ((Activity) context),
                permission.ACCESS_FINE_LOCATION );
            boolean checkShouldShowCoarse = Permission.shouldShowRequestPermissionRationale( ((Activity) context),
                permission.ACCESS_COARSE_LOCATION );
            if ( checkShouldShowFine || checkShouldShowCoarse ) {
                /*没有定位权限，不会弹出权限申请弹窗，解释需要权限的原因*/
                processShouldShowRequestPermissionRationale( new Runnable() {
                    @Override
                    public void run() {
                        /*没有定位权限，不会弹出权限申请弹窗，解释需要权限的原因，去app详情界面*/
                        StartForResult.registerForActivityResult( manager,
                            IntentBuilder.appSettingIntent( context ),
                            new ActivityResultCallback< ActivityResult >() {
                                @Override
                                public void onActivityResult( ActivityResult result ) {

                                    boolean checkFine = Permission.check( context, permission.ACCESS_FINE_LOCATION );
                                    boolean checkCoarse = Permission.check( context, permission.ACCESS_COARSE_LOCATION );
                                    if ( checkFine || checkCoarse ) {
                                        /*没有定位权限，不会弹出权限申请弹窗，解释需要权限的原因，去app详情界面，有权限了*/
                                        if ( CommonCode.couldLocation( context ) ) {
                                            /*没有定位权限，不会弹出权限申请弹窗，解释需要权限的原因，去app详情界面，有权限了，有定位服务*/
                                            notifyFailedResult( LOCATION_FUNCTION_FINE );
                                            if ( hasPermission != null ) {
                                                hasPermission.run();
                                            }
                                        } else {
                                            /*没有定位权限，不会弹出权限申请弹窗，解释需要权限的原因，去app详情界面，有权限了，没有定位服务*/
                                            processLocationServiceSetting( new Runnable() {
                                                @Override
                                                public void run() {
                                                    /*没有定位权限，不会弹出权限申请弹窗，解释需要权限的原因，去app详情界面，有权限了，没有定位服务，去手机设置开启定位服务*/
                                                    StartForResult.registerForActivityResult( manager,
                                                        IntentBuilder.settingIntent(),
                                                        new ActivityResultCallback< ActivityResult >() {
                                                            @Override
                                                            public void onActivityResult( ActivityResult result ) {
                                                                /*没有定位权限，不会弹出权限申请弹窗，解释需要权限的原因，去app
                                                                详情界面，有权限了，没有定位服务，去手机设置开启定位服务，开启定位为服务*/
                                                                if ( CommonCode.couldLocation( context ) ) {
                                                                    notifyFailedResult( LOCATION_FUNCTION_FINE );
                                                                    if ( hasPermission != null ) {
                                                                        hasPermission.run();
                                                                    }
                                                                } else {
                                                                     /*没有定位权限，不会弹出权限申请弹窗，解释需要权限的原因，去app
                                                                详情界面，有权限了，没有定位服务，去手机设置开启定位服务，没有开启定位为服务*/
                                                                    notifyFailedResult( LOCATION_SERVICE_SETTING_CLOSE );
                                                                }
                                                            }
                                                        } );
                                                }
                                            }, new Runnable() {
                                                @Override
                                                public void run() {
                                                    /*没有定位权限，不会弹出权限申请弹窗，解释需要权限的原因，去app详情界面，有权限了，没有定位服务，不去手机设置开启定位服务*/
                                                    notifyFailedResult( LOCATION_SERVICE_SETTING_CLOSE );
                                                }
                                            } );
                                        }
                                    } else {
                                        /*没有定位权限，不会弹出权限申请弹窗，解释需要权限的原因，去app详情界面，没有权限了*/
                                        notifyFailedResult( LOCATION_PERMISSION_DENY );
                                    }
                                }
                            } );
                    }
                }, new Runnable() {
                    @Override
                    public void run() {
                        /*没有定位权限，不会弹出权限申请弹窗，解释需要权限的原因，不去app详情界面*/
                        notifyFailedResult( LOCATION_PERMISSION_DENY );
                    }
                } );
            } else {
                /*没有定位权限，可以弹出权限申请弹窗，说明权限用处*/
                processRequestForPermission( new Runnable() {
                    @Override
                    public void run() {
                        /*没有定位权限，可以弹出权限申请弹窗，说明权限用处，去获取权限*/
                        Permission.registerForPermissionsResult(
                            manager,
                            new String[]{permission.ACCESS_FINE_LOCATION, permission.ACCESS_COARSE_LOCATION},
                            new ActivityResultCallback< Map< String, Boolean > >() {
                                @Override
                                public void onActivityResult( Map< String, Boolean > result ) {

                                    boolean all = true;
                                    for ( Boolean value : result.values() ) {
                                        if ( value != null && !value ) {
                                            /*没有同意权限*/
                                            all = false;
                                        }
                                    }
                                    if ( all ) {
                                        /*没有定位权限，可以弹出权限申请弹窗，说明权限用处，去获取权限，获取到权限*/
                                        if ( CommonCode.couldLocation( context ) ) {
                                            /*没有定位权限，可以弹出权限申请弹窗，说明权限用处，去获取权限，获取到权限，有定位服务*/
                                            notifyFailedResult( LOCATION_FUNCTION_FINE );
                                            if ( hasPermission != null ) {
                                                hasPermission.run();
                                            }
                                        } else {
                                            /*关闭了定位服务, 跳转设置界面*/
                                            processLocationServiceSetting( new Runnable() {
                                                @Override
                                                public void run() {
                                                    /*跳转设置界面*/
                                                    StartForResult.registerForActivityResult( manager,
                                                        IntentBuilder.settingIntent(),
                                                        new ActivityResultCallback< ActivityResult >() {
                                                            @Override
                                                            public void onActivityResult( ActivityResult result ) {
                                                                /*再次检测*/
                                                                if ( CommonCode.couldLocation( context ) ) {
                                                                    /*再次检测打开了服务*/
                                                                    notifyFailedResult( LOCATION_FUNCTION_FINE );
                                                                    if ( hasPermission != null ) {
                                                                        hasPermission.run();
                                                                    }
                                                                } else {
                                                                    /*再次检测没有打开服务*/
                                                                    notifyFailedResult( LOCATION_SERVICE_SETTING_CLOSE );
                                                                }
                                                            }
                                                        } );
                                                }
                                            }, new Runnable() {
                                                @Override
                                                public void run() {
                                                    /*不跳转设置界面*/
                                                    notifyFailedResult( LOCATION_SERVICE_SETTING_CLOSE );
                                                }
                                            } );
                                        }
                                    } else {
                                        /*请求权限失败*/
                                        notifyFailedResult( LOCATION_PERMISSION_DENY );
                                    }
                                }
                            } );
                    }
                }, new Runnable() {
                    @Override
                    public void run() {
                        /*没有定位权限，可以弹出权限申请弹窗，说明权限用处，不去获取权限*/
                        notifyFailedResult( LOCATION_PERMISSION_DENY );
                    }
                } );
            }
        }
    }

    /**
     * 请求定位权限之前先解释一下为什么使用,引导用户打开系统权限弹窗
     *
     * @param confirm 用户同意去请求之后的代码流程全部包含在此,需要调用{@link Runnable#run()}进行后面的流程
     * @param cancel  用户拒绝去请求之后的代码流程全部包含在此,需要调用{@link Runnable#run()}进行后面的流程
     */
    public void processRequestForPermission( Runnable confirm, Runnable cancel ) {

    }

    /**
     * 用户拒绝权限申请之后,引导用户打开app详情处理权限
     *
     * @param confirm 用户同意去请求之后的代码流程全部包含在此,需要调用{@link Runnable#run()}进行后面的流程
     * @param cancel  用户拒绝去请求之后的代码流程全部包含在此,需要调用{@link Runnable#run()}进行后面的流程
     */
    public void processShouldShowRequestPermissionRationale( Runnable confirm, Runnable cancel ) {

    }

    /**
     * 系统定位服务没有打开,引导用户打开手机设置打开定位服务
     *
     * @param confirm 用户同意去请求之后的代码流程全部包含在此,需要调用{@link Runnable#run()}进行后面的流程
     * @param cancel  用户拒绝去请求之后的代码流程全部包含在此,需要调用{@link Runnable#run()}进行后面的流程
     */
    public void processLocationServiceSetting( Runnable confirm, Runnable cancel ) {

    }

    /**
     * @param type {@link #LOCATION_SERVICE_SETTING_CLOSE,#LOCATION_PERMISSION_DENY,#LOCATION_FUNCTION_FINE}
     */
    public void notifyFailedResult( @LocationResult int type ) {

    }
}

